package br.com.mtg.movethegarbage.game;

import java.util.ArrayList;

import android.util.Log;
import br.com.mtg.movethegarbage.framework.Game;
import br.com.mtg.movethegarbage.framework.Graphics;

public class GameWorld
{
	Game game;
	Map map;
	Player player;
	ArrayList<Box> boxes;
	ArrayList<Bin> bins;
	int moves;

	public GameWorld(Game _game, Map _map)
	{
		game = _game;
		map = _map;
		boxes = new ArrayList<Box>();
		bins = new ArrayList<Bin>();
		moves = 0;
		float f;
		if (game.getGraphics().getWidth() / map.w < game.getGraphics().getHeight() / map.h)
		{
			Tile.TILE_SIZE = (int) (game.getGraphics().getWidth() / map.w);
			f = (float) Tile.TILE_SIZE * map.h;
			f = (game.getGraphics().getHeight() - f) / 2;
			map.minY = f;
			map.minX = 0;
		}
		else
		{
			Tile.TILE_SIZE = (int) (game.getGraphics().getHeight() / map.h);
			f = (float) Tile.TILE_SIZE * map.w;
			f = (game.getGraphics().getWidth() - f) / 2;
			map.minX = f;
			map.minY = 0;
		}
	}

	public void loadAndInitializeMap()
	{
		if (map.tiles == null)
		{
			try
			{
				map.read();
			}
			catch (Exception e)
			{
				Log.e("Map Error", "Error Reading Map File");
			}
		}
		map.initializeMap(this);
		map.initializeSpriteManagers(game.getGraphics());
	}

	public void movePlayer(int direction)
	{
		if (player == null)
			return;

		int xDirection, yDirection;
		switch (direction)
		{
			case Player.DIRECTION_RIGHT:
				xDirection = 1;
				yDirection = 0;
				player.setSprite(Assets.SPRITE_PLAYER_RIGHT);
				break;
			case Player.DIRECTION_LEFT:
				xDirection = -1;
				yDirection = 0;
				player.setSprite(Assets.SPRITE_PLAYER_LEFT);
				break;
			case Player.DIRECTION_UP:
				xDirection = 0;
				yDirection = 1;
				player.setSprite(Assets.SPRITE_PLAYER_UP);
				break;
			case Player.DIRECTION_DOWN:
				xDirection = 0;
				yDirection = -1;
				player.setSprite(Assets.SPRITE_PLAYER_DOWN);
				break;
			default:
				xDirection = 0;
				yDirection = 0;
				player.setSprite(Assets.SPRITE_PLAYER_DOWN);
		}

		moves++;
		int x = player.mapX;
		int y = player.mapY;
		Box b, b2;
		try
		{
			if (map.tiles[x + xDirection][y + yDirection].getTileID() == Tile.TILE_GROUND)
			{
				player.mapMove(xDirection, yDirection);
				player.move(xDirection * Tile.TILE_SIZE, yDirection * Tile.TILE_SIZE);
				for (int i = 0; i < boxes.size(); i++)
				{
					b = boxes.get(i);
					if (b.mapX == player.mapX && b.mapY == player.mapY)
					{
						if (map.tiles[x + 2 * xDirection][y + 2 * yDirection].getTileID() == Tile.TILE_GROUND)
						{
							b.mapMove(xDirection, yDirection);
							b.move(xDirection * Tile.TILE_SIZE, yDirection * Tile.TILE_SIZE);
							for (int j = 0; j < boxes.size(); j++)
							{
								if (i == j)
									continue;
								else
									b2 = boxes.get(j);
								if (b.mapX == b2.mapX && b.mapY == b2.mapY)
								{
									b.mapMove(-1 * xDirection, -1 * yDirection);
									b.move(-1 * xDirection * Tile.TILE_SIZE, -1 * yDirection * Tile.TILE_SIZE);
									player.mapMove(-1 * xDirection, -1 * yDirection);
									player.move(-1 * xDirection * Tile.TILE_SIZE, -1 * yDirection * Tile.TILE_SIZE);
								}
							}
						}
						else
						{
							player.mapMove(-1 * xDirection, -1 * yDirection);
							player.move(-1 * xDirection * Tile.TILE_SIZE, -1 * yDirection * Tile.TILE_SIZE);
						}
						return;
					}
				}
			}
		}
		catch (ArrayIndexOutOfBoundsException e)
		{
			Log.e("GameWorld", "Array out of bounds");
		}
	}

	public void instancePlayer(Player _player)
	{
		player = _player;
	}

	public void instanceBox(Box box)
	{
		boxes.add(box);
	}

	public void instanceBin(Bin bin)
	{
		bins.add(bin);
	}

	public void draw(Graphics graphics)
	{
		map.draw(graphics);
		for (Bin b : bins)
			b.draw(graphics);
		for (Box b : boxes)
			b.draw(graphics);
		player.draw(graphics);
	}

	public boolean update()
	{
		Box box;
		Bin bin;
		boolean boxMatch = false;
		for (int i = 0; i < boxes.size(); i++)
		{
			boxMatch = false;
			box = boxes.get(i);
			for (int j = 0; j < bins.size(); j++)
			{
				bin = bins.get(j);
				if (box.mapX == bin.mapX && box.mapY == bin.mapY)
					boxMatch = true;
			}
			if (!boxMatch)
				return false;
		}
		return true;
	}

	public int getGameScore()
	{
		return moves;
	}
}
